(function($) {
    function Province(id, name) {
        this.id = id;
        this.name = name;
    }

    function City(id, name, province_id) {
        this.id = id;
        this.name = name;
        this.province_id = province_id;
    }

    function Area(id, name, city_id) {
        this.id = id;
        this.name = name;
        this.city_id = city_id;
    }

    var province_list = {
    {foreach $provinces as $info}
        {$info.id} : new Province({$info.id}, "{$info.name|escape}")
        {if ! $info@last},{/if}
    {/foreach}
    };

    var city_list = {
    {foreach $citys as $info}
        {$info.id} : new City({$info.id}, "{$info.name|escape}", {$info.province_id})
        {if ! $info@last},{/if}
    {/foreach}
    };

    var area_list = {
    {foreach $areas as $info}
        {$info.id} : new Area({$info.id}, "{$info.name|escape}", {$info.city_id})
        {if ! $info@last},{/if}
    {/foreach}
    };


    function init_province_city_area_dom(province_dom_id, city_dom_id, area_dom_id, area_id, city_id, province_id) {
        var province_dom = $('#' + province_dom_id);
        var city_dom = $('#' + city_dom_id);
        var area_dom = $('#' + area_dom_id);

        $.each(province_list, function(k, v) {
            $('<option>').attr('value', v.id).html(v.name).appendTo(province_dom);
        });

        // Add events
        province_dom.change(function() {
            set_city_dom(city_dom_id, $(this).val());
            set_area_dom(area_dom_id, city_dom.val());
        });

        city_dom.change(function() {
            set_area_dom(area_dom_id, $(this).val());
        });

        if (typeof(area_id) != 'undefined' && area_id != '') {
            // area_id prior to city_id
            city_id = area_list[area_id].city_id;
            province_id = city_list[city_id].province_id;
            set_area_dom(area_dom_id, city_id);
            set_city_dom(city_dom_id, province_id);
            area_dom.val(area_id);
            city_dom.val(city_id);
            province_dom.val(province_id);

        } else if (typeof(city_id) != 'undefined' && city_id != '') {
            // city_id prior to province_id
            province_id = city_list[city_id].province_id;
            set_area_dom(area_dom_id, city_id);
            set_city_dom(city_dom_id, province_id);
            city_dom.val(city_id);
            province_dom.val(province_id);

        } else if (typeof(province_id) != 'undefined' && province_id != '') {
            // Set province
            set_city_dom(city_dom_id, province_id);
            province_dom.val(province_id);
        }
    }

    
    function init_province_city_dom(province_dom_id, city_dom_id, city_id, province_id) {
        var province_dom = $('#' + province_dom_id);
        var city_dom = $('#' + city_dom_id);

        $.each(province_list, function(k, v) {
            $('<option>').attr('value', v.id).html(v.name).appendTo(province_dom);
        });

        province_dom.change(function() {
            set_city_dom(city_dom_id, $(this).val());
        });

        // city_value prior to province_id
        if (typeof(city_id) != 'undefined' && city_id != '') {
            // Set city and override province
            province_id = city_list[city_id].province_id;
            set_city_dom(city_dom_id, province_id);
            city_dom.val(city_id);
            province_dom.val(province_id);
        } else if (typeof(province_id) != 'undefined' && province_id != '') {
            // Set province
            set_city_dom(city_dom_id, province_id);
            province_dom.val(province_id);
        }
    }


    function set_area_dom(area_dom_id, city_id) {
        var area_dom = $('#' + area_dom_id);

        // Remove all except value == ''
        area_dom.children('[value!=""]').remove();

        $.each(area_list, function(k, v) {
            if (v.city_id == city_id) {
                $('<option>').attr('value', v.id).html(v.name).appendTo(area_dom);
            }
        });
    }


    function get_area_name(area_id, default_name) {
        if (typeof(area_list[area_id]) == 'undefined') {
            return typeof(default_name) != 'undefined' ? default_name : null;
        }

        return area_list[area_id].name;
    }
    

    function set_city_dom(city_dom_id, province_id) {
        var city_dom = $('#' + city_dom_id);

        // Remove all except value == ''
        city_dom.children('[value!=""]').remove();

        $.each(city_list, function(k, v) {
            if (v.province_id == province_id) {
                $('<option>').attr('value', v.id).html(v.name).appendTo(city_dom);
            }
        });
    }


    function get_city_name(city_id, default_name) {
        if (typeof(city_list[city_id]) == 'undefined') {
            return typeof(default_name) != 'undefined' ? default_name : null;
        }

        return city_list[city_id].name;
    }


    function get_province_name(city_id, default_name) {
        if (typeof(city_list[city_id]) == 'undefined') {
            return typeof(default_name) != 'undefined' ? default_name : null;
        }

        return province_list[city_list[city_id].province_id].name;
    }


    // Public function
    window.init_province_city_area_dom = init_province_city_area_dom;
    window.init_province_city_dom = init_province_city_dom;
    window.get_area_name = get_area_name;
    window.get_city_name = get_city_name;
    window.get_province_name = get_province_name;
})(jQuery);
